#include <gtest/gtest.h>

#include "MemoryDBTest.h"

#include "helper/sqlite/IDB.h"
#include "helper/sqlite/Statement.h"

class DBCommandTest : public test::MemoryDBTest {
};

TEST_F(DBCommandTest, dml){
  std::error_code ec;
  auto && stmt = db().createStatement("insert into tab1 values ('1111', 23);", ec); 
  ASSERT_TRUE(stmt && !ec);

  auto && r = stmt->execute();
  ASSERT_TRUE(r);

  ASSERT_EQ(1, r.affectRows());
}
TEST_F(DBCommandTest, dml_PrepareInput){
  std::string text("3333"); //alive in executing

  {
    std::error_code ec;
    auto && stmt = db().createStatement("insert into tab1 values (?, ?);", ec);
    ASSERT_TRUE(stmt && !ec);

    int iv =  44;
    ec = stmt->prepareInput([&text, iv](auto & stmt) {
        std::error_code ec = stmt.textBind(1, text); 
        if(ec) return ec;

        ec = stmt.intBind(2, iv);
        if(ec) return ec;
        return ec;
      });
    ASSERT_EQ(std::error_code(), ec);

    auto && r = stmt->execute();
    ASSERT_TRUE(r);
    ASSERT_EQ(1, r.affectRows());
  }

  {
    std::error_code ec;
    auto && stmt = db().createStatement("delete from tab1 where one = ?", ec);
    ASSERT_TRUE(stmt && !ec);

    ec = stmt->textBind(1, text);
    ASSERT_EQ(std::error_code(), ec);

    auto && r = stmt->execute();
    ASSERT_TRUE(r);
    ASSERT_EQ(1, r.affectRows());
  }
}

TEST_F(DBCommandTest, dml_reBinding){
  std::error_code ec;
  auto && stmt = db().createStatement("insert into tab1 values (?, ?);", ec);
  ASSERT_TRUE(stmt && !ec);

  { // insert 3333, 44 with bind 
    std::string text("3333"); //alive in executing
    int iv =  44;
    ec = stmt->prepareInput([&text, iv](auto & stmt) {
        std::error_code ec = stmt.textBind(1, text); 
        if(ec) return ec;

        ec = stmt.intBind(2, iv);
        if(ec) return ec;
        return ec;
    });
    ASSERT_EQ(std::error_code(), ec);

    auto && r = stmt->execute();
    ASSERT_TRUE(r);
    ASSERT_EQ(1, r.affectRows());
  }

  { // insert 4444, 88 with rebind
    ASSERT_EQ(0, stmt->reset().value());
    ASSERT_TRUE(!stmt->clearBindings());

    std::string text("4444"); //alive in executing
    int iv = 88;
    ec = stmt->prepareInput([&text, iv](auto & stmt) {
        std::error_code ec = stmt.textBind(1, text); 
        if(ec) return ec;

        ec = stmt.intBind(2, iv);
        if(ec) return ec;
        return ec;
    });
    ASSERT_EQ(std::error_code(), ec);

    auto && r = stmt->execute();
    ASSERT_TRUE(r);
    ASSERT_EQ(1, r.affectRows());
  }
}
